package com.cskaoyan.wordmemorize.service.impl;

import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cskaoyan.wordmemorize.auth.SaUserCheckPermission;
import com.cskaoyan.wordmemorize.common.constant.CommonConstant;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cskaoyan.wordmemorize.common.entity.BaseDO;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.controller.app.MyController;
import com.cskaoyan.wordmemorize.converter.UserPrivilegeConverter;
import com.cskaoyan.wordmemorize.dao.entity.*;
import com.cskaoyan.wordmemorize.dao.mapper.*;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.dto.admin.UserVocAISituationDTO;
import com.cskaoyan.wordmemorize.dto.app.*;
import com.cskaoyan.wordmemorize.request.AIReviewReadCommand;
import com.cskaoyan.wordmemorize.request.PageRequest;
import com.cskaoyan.wordmemorize.request.UserFavoriteCommand;
import com.cskaoyan.wordmemorize.request.UserVocExampleSentenceCommand;
import com.cskaoyan.wordmemorize.service.UserPrivilegeService;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.Resource;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.springframework.ai.chat.client.ChatClient; // todo 我加的
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class UserPrivilegeServiceImpl implements UserPrivilegeService {


    @Autowired
    UserFavoriteMapper userFavoriteMapper;

    @Autowired
    VocMapper vocMapper;

    @Autowired
    UserPrivilegeConverter userPrivilegeConverter;

    @Autowired
    UserVocExampleSentenceMapper userVocExampleSentenceMapper;

    // todo 我加的
    @Value("classpath:/prompt/ai-read-system-message.st")
    Resource systemResource;
    @Value("classpath:/prompt/ai-read-user-message.st")
    Resource userResource;
    @Autowired
    UserPrivilegeHistoryMapper privilegeUseStatisticsMapper;
    @Autowired
    UserVocBoundStatisticsMapper boundStatisticsMapper;
    @Autowired
    UserVocBoundLogMapper boundLogMapper;
    @Autowired
    MyController myController;

    @Autowired
    UserVocRevMapper userVocRevMapper;

    @Autowired
    UserPrivilegeHistoryMapper userPrivilegeHistoryMapper;
    @Autowired
    UserNotRememberMapper userNotRememberMapper;

    @Autowired
    VocBookMapper vocBookMapper;

    @Autowired
    VocChapBookMapper vocChapBookMapper;


    @Autowired
    UserVocAISituationMapper userVocAISituationMapper;

    @Autowired
    UserVocAISituationOptionMapper userVocAISituationOptionMapper;


    // todo AI阅读
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<AIReviewReadDTO> getAIReviewReadContent(AIReviewReadCommand command, Long userId) {
        // todo 检查用户权限和使用次数
        checkUserPrivilege(userId);

        // todo 准备提示词并调用AI
        List<AIReviewReadDTO> result = generateContent(command);

        // todo 更新用户使用记录
        updateUserUsage(userId);

        return result;
    }

    private void checkUserPrivilege(Long userId) {
        // todo 查询用户已使用次数
        UserPrivilegeUseStatisticsDO statistics = privilegeUseStatisticsMapper.selectByUserIdAndPrivilegeCode(
                userId,
                CommonConstant.USER_PRIVILEGE_CODE_AI_READ
        );

        int usedCount = statistics == null ? 0 : statistics.getUseCount(); // todo 防止空指针异常

        // todo 如果超过10次，检查单词上限
        if (usedCount > 10) {


            // todo 如果可用单词上限少于10, 连一次使用抵扣都换不了直接报异常
            Integer available = boundStatisticsMapper.selectAvailableByUserId(userId);
            if (available == null || available < 10) {
                throw new BusinessException(ResultCodeEnum.USER_VOC_BOUND_NOT_ENOUGH);
            }
        }
    }
    private List<AIReviewReadDTO> generateContent(AIReviewReadCommand command) {
        try {
            // todo 创建系统提示词
            SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
            Message systemMessage = systemPromptTemplate.createMessage();


            // 2. 准备用户提示词参数
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("situation", command.getSituationName());
            paramMap.put("option", command.getOptionName());
            paramMap.put("words", command.getVocList().toString());

            // 根据场景设置type参数
            String type = switch (command.getSituationName()) {
                case "教育模式" -> "短文";
                case "对话模式" -> "对话";
                default -> "故事";
            };
            paramMap.put("type", type);

            // todo 创建用户提示词
            PromptTemplate userPrompt = new PromptTemplate(userResource, paramMap);
            Message userMessage = userPrompt.createMessage();

            // todo 构建完整提示词并调用AI
            Prompt prompt = new Prompt(List.of(userMessage, systemMessage));

            return myController.getChatClient().prompt(prompt)
                    .call()
                    .entity(new ParameterizedTypeReference<List<AIReviewReadDTO>>() {});
        } catch (Exception e) {
            throw new BusinessException(ResultCodeEnum.FAIL);
        }
    }

    private void updateUserUsage(Long userId) {
        // todo 查询当前使用记录
        UserPrivilegeUseStatisticsDO statistics = privilegeUseStatisticsMapper.selectByUserIdAndPrivilegeCode(
                userId,
                CommonConstant.USER_PRIVILEGE_CODE_AI_READ
        );

        // todo 处理首次使用情况
        if (statistics == null) {
            statistics = UserPrivilegeUseStatisticsDO.builder()
                    .userId(userId)
                    .privilegeCode(CommonConstant.USER_PRIVILEGE_CODE_AI_READ)
                    .useCount(1)
                    .build();
            privilegeUseStatisticsMapper.insert(statistics);
            return; // todo 跳过更新逻辑
        }

        // todo 更新使用次数
        int updateCount = privilegeUseStatisticsMapper.incrementUseCount(statistics.getId());
        if (updateCount != 1) {
            throw new BusinessException(ResultCodeEnum.FAIL); // todo 更新失败了捏
        }

        // todo 查询更新后的使用次数
        int newUsedCount = privilegeUseStatisticsMapper.selectUseCountById(statistics.getId());

        // todo 超过10次后扣减单词上限
        if (newUsedCount > 10) {
            updateUserWordBound(userId);
        }
    }

    private void updateUserWordBound(Long userId) {
        // todo 扣减单词上限
        int updated = boundStatisticsMapper.deductAvailable(userId, 10);
        if (updated == 0) {
            throw new BusinessException(ResultCodeEnum.USER_VOC_BOUND_NOT_ENOUGH);
        }

        // todo 记录单词上限变化日志
        UserVocBoundLogDO log = UserVocBoundLogDO.builder()
                .userId(userId)
                .type(CommonConstant.USER_VOC_BOUND_CHANGE_TYPE_EXCHANGE)
                .description(CommonConstant.USER_VOC_BOUND_DESCRIPTION_AI_READ)
                .count(10)
                .logDate(LocalDate.now())
                .build();
        boundLogMapper.insert(log);
    }


    // todo APP端单个添加收藏单词
    @Override
    public void addFavorite(UserFavoriteCommand userFavoriteCommand, Long userId) {

        // 转化成DO对象，但userId为null
        UserFavoriteDO userFavoriteDO = userPrivilegeConverter.userFavoriteCommand2DO(userFavoriteCommand);

        // 补全userId
        userFavoriteDO.setUserId(userId);

        // 往数据库添加对象
        userFavoriteMapper.insert(userFavoriteDO);

    }

    // todo APP端批量添加收藏单词
    @Override
    public void addFavoriteBulk(List<UserFavoriteCommand> userFavoriteCommand, Long userId) {


        for (UserFavoriteCommand word : userFavoriteCommand) {

            // 反复调用单个添加收藏单词的方法

            // 根据单词Id，获得单词的英文，并返回添加

            // 根据单词Id，找到VOC表中的单词
            VocDO vocdo = vocMapper.selectById(word.getVocId());

            // 把这个单词的英文 赋值给 word中的英文
            word.setVocContent(vocdo.getContent());

            // 默认从单词书批量增加的单词为未选择记忆
            word.setSelected(0);


            // -------查重

            // 为了避免同时出现一个单词被收藏多遍，每个单词查重以后才添加
            LambdaQueryWrapper<UserFavoriteDO> LambdaQueryWrapper = new LambdaQueryWrapper<>();
            LambdaQueryWrapper
                    .in(UserFavoriteDO::getVocId, word.getVocId())
                    .eq(UserFavoriteDO::getUserId, userId)
                    .eq(UserFavoriteDO::getIsDeleted, 0);

            // 如果不存在“这个用户已收藏该单词，并且未删除”的情况，那么可以放心添加
            UserFavoriteDO Do = userFavoriteMapper.selectOne(LambdaQueryWrapper);

            if (Do == null) {
                // 调用单个添加收藏单词的方法
                addFavorite(word, userId);
            }

        }

    }


    // todo APP端取消收藏单词
    @Override
    public void cancelFavorite(List<Long> ids, Long userId) {

        // 根据单词Id和用户Id，找到目标DO
        LambdaQueryWrapper<UserFavoriteDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();

//        // 只有一个数据
//        LambdaQueryWrapper
//                .eq(UserFavoriteDO::getVocId, ids.get(0))
//                .eq(UserFavoriteDO::getUserId,userId);


        // 可以处理多个数据
        lambdaQueryWrapper
                .in(UserFavoriteDO::getVocId, ids)
                .eq(UserFavoriteDO::getUserId, userId);

        userFavoriteMapper.delete(lambdaQueryWrapper);
    }

    // todo APP端获取单词收藏列表--根据关键字搜索
    @Override
    public PageDTO<UserFavoriteDTO> getUserFavoriteList(PageRequest pageRequest, Long userId) {


        // 创建空的条件构造器，用来全表查询
        LambdaQueryWrapper<UserFavoriteDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();


        // todo 没给关键字 或 为空格, 则全表查询
        if (pageRequest.getKeyword() == null && pageRequest.getKeyword().isEmpty()) {

            // 条件构造器没有信息时，为全表查询
            // 封装成List<UserFavoriteDO>
            List<UserFavoriteDO> userFavoriteDOs = userFavoriteMapper.selectList(lambdaQueryWrapper);

            // 老师提供好的转化方法，把List<UserFavoriteDO>转成PageDTO<UserFavoriteDTO>，并返回
            return userPrivilegeConverter.userFavoriteDOPage2PageDTO(userFavoriteDOs, (long) userFavoriteDOs.size());
        }


        // todo 有关键字 则做分页查询

        // 匹配相似的单词名
        lambdaQueryWrapper.like(UserFavoriteDO::getVocContent, pageRequest.getKeyword());

        // 把一个或多个结果，塞进定制的List里
        List<UserFavoriteDO> userFavoriteDOs = userFavoriteMapper.selectList(lambdaQueryWrapper);

        // 老师提供好的转化方法，把List<UserFavoriteDO>转成PageDTO<UserFavoriteDTO>，并返回
        return userPrivilegeConverter.userFavoriteDOPage2PageDTO(userFavoriteDOs, (long) userFavoriteDOs.size());
    }


    // todo APP端添加用户自建例句
    @Override
    public void addUserVocSentence(UserVocExampleSentenceCommand command, Long userId) {

        // 把UserVocExampleSentenceCommand 转化成 UserVocExampleSentenceDO
        UserVocExampleSentenceDO userVocExampleSentenceDO = userPrivilegeConverter.userVocExampleSentenceCommand2DO(command);

        // 设置用户Id
        userVocExampleSentenceDO.setUserId(userId);

        // 插入DO对象
        userVocExampleSentenceMapper.insert(userVocExampleSentenceDO);

    }

    // todo APP端获取用户自建例句
    @Override
    public PageDTO<DisplayUserVocSentenceDTO> getUserVocSentence(PageRequest pageRequest, Long userId) {

        // 构造查询条件
        LambdaQueryWrapper<UserVocExampleSentenceDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserVocExampleSentenceDO::getUserId, userId)
                .like(pageRequest.getKeyword() != null && !pageRequest.getKeyword().isEmpty(),
                        UserVocExampleSentenceDO::getVocContent, pageRequest.getKeyword());

        // 构造分页对象
        Page<UserVocExampleSentenceDO> page = new Page<>(pageRequest.getPageNum(), pageRequest.getCount());

        // 执行分页查询
        Page<UserVocExampleSentenceDO> userVocExampleSentencePage = userVocExampleSentenceMapper.selectPage(page, queryWrapper);

        // 转换为 DTO
        List<DisplayUserVocSentenceDTO> displayUserVocSentenceDTOs = userVocExampleSentencePage.getRecords().stream()
                .map(userVocExampleSentenceDO -> {
                    DisplayUserVocSentenceDTO dto = new DisplayUserVocSentenceDTO();
                    dto.setUserId(String.valueOf(userVocExampleSentenceDO.getUserId()));
                    dto.setVocId(String.valueOf(userVocExampleSentenceDO.getVocId()));
                    dto.setVocContent(userVocExampleSentenceDO.getVocContent());
                    dto.setSentences(List.of(new UserVocSentenceDTO(
                            String.valueOf(userVocExampleSentenceDO.getId()),
                            userVocExampleSentenceDO.getSentence(),
                            userVocExampleSentenceDO.getMeaning()
                    )));
                    return dto;
                })
                .collect(Collectors.toList());

        // 封装并返回分页结果
        return new PageDTO<>(displayUserVocSentenceDTOs, userVocExampleSentencePage.getTotal());
    }

    // todo APP端更新用户自建例句
    @Override
    public void updateUserVocSentence(UserVocExampleSentenceCommand command, Long userId) {

        // 要修改的是什么东西？ -> 需要传一个Wrapper
        // 去看一下这个url携带的一些参数

        // 构造Wrapper
        LambdaUpdateWrapper<UserVocExampleSentenceDO> userUpdateWrapper = new LambdaUpdateWrapper<>();
        userUpdateWrapper
                .eq(UserVocExampleSentenceDO::getId, command.getId())
                .eq(UserVocExampleSentenceDO::getVocId, command.getVocId())
                .set(UserVocExampleSentenceDO::getUserId, userId)
                .set(UserVocExampleSentenceDO::getSentence, command.getSentence())
                .set(UserVocExampleSentenceDO::getMeaning, command.getMeaning())
                .set(UserVocExampleSentenceDO::getVocContent, command.getVocContent());
        // 调用Mapper自带的update方法，传入Wrapper
        userVocExampleSentenceMapper.update(userUpdateWrapper);

    }

    // todo APP端删除用户自建例句
    @Override
    public void deleteUserVocSentence(Long id) {

    }

    // todo APP端表示不想背
    @Override
    @Transactional
    public void notRemember(Long vocId, Long userId) {
        // 第一种情况： 用户单词已选，标不想背。
        //      在user_voc_rev表中删除该表项，将该表项加入user_not_remebmer表中
        //      两个操作需要同时发生，所以需要在一个事务中

        //  判断单词是否在复习列表中，构造Wrapper查询
        LambdaQueryWrapper<UserVocRevDO> revQueryWrapper = new LambdaQueryWrapper<>();
        revQueryWrapper.eq(UserVocRevDO::getVocId,vocId)
                .eq(UserVocRevDO::getUserId,userId);
        UserVocRevDO userVocRevDO = userVocRevMapper.selectOne(revQueryWrapper);

        // 如果不为空，即单词已经在复习列表，添加事务同时进行两个操作
        if (userVocRevDO != null){
            //在user_voc_rev表中删除该表项
            userVocRevMapper.deleteById(userVocRevDO.getId());
            //在user_not_remebmer表中添加
            UserNotRememberDO userNotRememberDO = new UserNotRememberDO();
            userNotRememberDO.setUserId(userId);
            userNotRememberDO.setVocId(vocId);
            userNotRememberMapper.insert(userNotRememberDO);
        }

        // 还有一种情况，单词未选，用户标识不想背，无法再选择，这个情况是在获取单词列表那里实现的。

    }

    // todo APP端取消标识不想背
    @Override
    public void cancelNotRemember(Long vocId, Long userId) {
        // 取消标识不想背就是在user_not_remember表中删除该单词的表项（根据vocId）
        // 现在思考操作这张表的是哪个Mapper   ->  UserNotRememberMapper
        //UserNotRememberDO
        // 直接new一个DO对象的方式是错误的
        //UserNotRememberDO userNotRememberDO = new UserNotRememberDO();
        //userNotRememberDO.setVocId(vocId);
        //userNotRememberDO.setUserId(userId);
        LambdaQueryWrapper<UserNotRememberDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserNotRememberDO::getUserId, userId)
                .eq(UserNotRememberDO::getVocId, vocId);
        UserNotRememberDO userNotRememberDO = userNotRememberMapper.selectOne(queryWrapper);

        userNotRememberMapper.deleteById(userNotRememberDO);

    }

    // todo APP端获取选词填空题列表
    @Override
    public List<UserReviewFillWordDTO> getUserReviewFillWordTopics(List<Long> vocIds) {
        return null;
    }

    // todo APP端获取单选题目列表
    @Override
    public List<UserReviewSingleChoiceDTO> getVocSingleChoiceTopic(List<Long> vocIds) {
        return null;
    }


    // todo APP端获取AI阅读模式以及选项
    @Override
    public List<UserVocAISituationDTO> getAIReviewReadOptions() {

        // 先获取所有已上架status为1的AI阅读模式
        LambdaQueryWrapper<UserVocAISituationDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserVocAISituationDO::getStatus,1);
        List<UserVocAISituationDO> userVocAISituationDOs = userVocAISituationMapper.selectList(lambdaQueryWrapper);

        // 遍历每个AI阅读模式
        for (UserVocAISituationDO userVocAISituationDO : userVocAISituationDOs) {

            // 再获取每个AI阅读模式的选项
            LambdaQueryWrapper<UserVocAISituationOptionDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserVocAISituationOptionDO::getSituationId,userVocAISituationDO.getId());
            List<UserVocAISituationOptionDO> userVocAISituationOptionDOs = userVocAISituationOptionMapper.selectList(queryWrapper);

            // 把选项设置到AI阅读模式中
            userVocAISituationDO.setOptions(userVocAISituationOptionDOs);
        }

        // 把所有的AI阅读模式转化成DTO
        List<UserVocAISituationDTO> userVocAISituationDTOs = userPrivilegeConverter.userVocAISituationDOs2DTOs(userVocAISituationDOs);

        // 返回DTO
        return userVocAISituationDTOs;
    }


    // todo APP端获取用户剩余免费AI阅读次数
    @Override
    public Integer getUserVocAIReadRemainFreeCount(Long userId) {

        // 用户只有10次免费AI阅读次数
        Integer freeMaxCount = 10;

        // 根据用户ID，获取用户特权已使用次数
        LambdaQueryWrapper<UserPrivilegeUseStatisticsDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserPrivilegeUseStatisticsDO::getUserId,userId);

        UserPrivilegeUseStatisticsDO userPrivilegeUseStatisticsDO = privilegeUseStatisticsMapper.selectOne(queryWrapper);
        if(userPrivilegeUseStatisticsDO == null){
            // todo 如果对象为空说明新用户注册, 返回10
            return 10;
        }

        // 用户剩余次数 = 免费次数 - 已使用次数
        Integer remainCount = freeMaxCount - userPrivilegeUseStatisticsDO.getUseCount();

        if (remainCount >= 0) {
            return remainCount;
        } else { // 如果用户已使用次数超过免费次数，返回0
            return 0;
        }
    }

    // todo APP端获取词书进度
    @Override
    public UserVocBookStatisticsDTO getSelectedBookStatistics(Long userId, Long bookId) {

        // 类UserVocRevDO     映射器UserVocRevMapper    表user_voc_rev     关于所有人的复习间隔 和 复习
        // 类VocChapBookDO    映射器VocChapBookMapper   表voc_chap_book    哪本书有包含了哪些具体单词
        // 类VocBookDO        映射器VocBookMapper       表voc_book         各书本的单词数量、出版细节

        // todo MyBatis Plus 本身并不直接支持多表关联查询，所以这里使用它的子查询功能

        // 不熟的单词数量
        LambdaQueryWrapper<UserVocRevDO> unFamiliarLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 复习间隔=1
        unFamiliarLambdaQueryWrapper
                .eq(UserVocRevDO::getReviewInterval, 1)
                .eq(UserVocRevDO::getUserId, userId)
                .eq(UserVocRevDO::getIsDeleted, 0)
                .inSql(UserVocRevDO::getVocId,
                        "SELECT voc_id FROM voc_chap_book WHERE book_id = " + bookId
                );
//                .inSql(UserVocRevDO::getVocId,
//                        new LambdaQueryWrapper<VocChapBookDO>()
//                                .select(VocChapBookDO::getVocId)
//                                .eq(VocChapBookDO::getBookId, bookId)
//                                .getSqlSelect());


        // 查出符合数量，然后Long转Integer
        Integer unFamiliar = userVocRevMapper.selectCount(unFamiliarLambdaQueryWrapper).intValue();


        // 一般的单词数量
        LambdaQueryWrapper<UserVocRevDO> generalLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 1<复习间隔<365
        generalLambdaQueryWrapper
                .gt(UserVocRevDO::getReviewInterval, 1)
                .lt(UserVocRevDO::getReviewInterval, 365)
                .eq(UserVocRevDO::getUserId, userId)
                .eq(UserVocRevDO::getIsDeleted, 0)
                .inSql(UserVocRevDO::getVocId,
                        "SELECT voc_id FROM voc_chap_book WHERE book_id = " + bookId
                );

        // 查出符合数量，然后Long转Integer
        Integer general = userVocRevMapper.selectCount(generalLambdaQueryWrapper).intValue();


        // 熟悉的单词数量
        LambdaQueryWrapper<UserVocRevDO> familiarLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 复习间隔>=365
        familiarLambdaQueryWrapper
                .ge(UserVocRevDO::getReviewInterval, 365)
                .eq(UserVocRevDO::getUserId, userId)
                .eq(UserVocRevDO::getIsDeleted, 0)
                .inSql(UserVocRevDO::getVocId,
                        "SELECT voc_id FROM voc_chap_book WHERE book_id = " + bookId
                );
        // 查出符合数量，然后Long转Integer
        Integer familiar = userVocRevMapper.selectCount(familiarLambdaQueryWrapper).intValue();


        // 已选未学的单词数量--未开始的单词
        LambdaQueryWrapper<UserVocRevDO> notStartedLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 复习间隔=0 或者为 null ，因为不知道新选择的单词是怎样的
        notStartedLambdaQueryWrapper
                // 为null 或为 0
                .and(wrapper -> wrapper
                        .isNull(UserVocRevDO::getReviewInterval)
                        .or()
                        .eq(UserVocRevDO::getReviewInterval, 0)
                )
                .eq(UserVocRevDO::getUserId, userId)
                .eq(UserVocRevDO::getIsDeleted, 0)
                .inSql(UserVocRevDO::getVocId,
                        "SELECT voc_id FROM voc_chap_book WHERE book_id = " + bookId
                );
        // 查出符合数量，然后Long转Integer
        Integer notStarted = userVocRevMapper.selectCount(notStartedLambdaQueryWrapper).intValue();


        // 单词总数
        // 找到对应的VocBookDO
        LambdaQueryWrapper<VocBookDO> totalQueryWrapper = new LambdaQueryWrapper<>();
        totalQueryWrapper.eq(VocBookDO::getId, bookId);
        VocBookDO vocBookDO = vocBookMapper.selectOne(totalQueryWrapper);
        // 反射找到单词总数
        Integer total = vocBookDO.getVocCount();


        // 未选单词数量
        Integer unSelected = total - unFamiliar - general - familiar - notStarted;


        // 自建一个DTO，然后往里面塞信息
        UserVocBookStatisticsDTO userVocBookStatisticsDTO = new UserVocBookStatisticsDTO();

        userVocBookStatisticsDTO.setTotal(total);
        userVocBookStatisticsDTO.setUnFamiliar(unFamiliar);
        userVocBookStatisticsDTO.setGeneral(general);
        userVocBookStatisticsDTO.setFamiliar(familiar);
        userVocBookStatisticsDTO.setNotStarted(notStarted);
        userVocBookStatisticsDTO.setUnSelected(unSelected);

        return userVocBookStatisticsDTO;

    }



}
